using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.IO;
using ChannelVN.CMS.DynamicLayout.FrontEnd.Base;
using ChannelVN.Cached.Common;
using ChannelVN.Cached.Config;
using ChannelVN.Cached;
using ChannelVN.Cached.Entity;

namespace ChannelVN.Cached.Base
{
    public abstract class ControlBase : DynamicControlBase
    {
        #region Abstract members
        public abstract string CacheConfigName { get; }
        public abstract bool IsCachedChanged(long newsId, string zoneId, long tagId);
        #endregion

        public bool CachedThisControl { get { return null != ControlCacheSetting && ControlCacheSetting.EnableCache; } }
        public bool UseDynamicLayout { get { return null != ControlCacheSetting && ControlCacheSetting.EnableDynamicLayout; } }

        public string CacheData { get; set; }

        public ControlSettingItem ControlCacheSetting { get; set; }

        public string ClientCacheName { get; set; }

        protected bool HasCacheData
        {
            get
            {
                return !string.IsNullOrEmpty(CacheData);
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            if (!CacheController.IsCachedDeleting)
            {
                if (!HasCacheData || UseDynamicLayout ||
                    (CacheController.IsCachedUpdating &&
                     IsCachedChanged(QueryStrings.CachedNewsId, QueryStrings.CachedZone, QueryStrings.CachedTagId)))
                {
                    if (UseDynamicLayout) OnLoadDynamicControl();

                    base.OnLoad(e);
                }
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            try
            {
                if (CacheController.IsCachedDeleting) return;

                if ((!string.IsNullOrEmpty(CacheConfigName) && CachedThisControl) || UseDynamicLayout)
                {
                    var strBuilder = new StringBuilder();
                    using (var strWriter = new StringWriter(strBuilder))
                    {
                        using (var htmlWriter = new HtmlTextWriter(strWriter))
                        {
                            var cacheSetting = CacheSettings.GetCurrentSettings();
                            var controlSetting = ControlCacheSetting;
                            if (null != controlSetting) EnableViewState = controlSetting.EnableViewState;

                            base.Render(htmlWriter);

                            if (!HasCacheData || UseDynamicLayout ||
                                (CacheController.IsCachedUpdating && IsCachedChanged(QueryStrings.CachedNewsId, QueryStrings.CachedZone, QueryStrings.CachedTagId)))
                            {
                                var html = strBuilder.ToString();

                                if (UseDynamicLayout)
                                {
                                    html = OnRenderDynamicControl(html);
                                }

                                if (AppConfigs.AllowWrite1Line)
                                {
                                    html = Lib.CompressHtmlContent(html);
                                }

                                if (!IsPostBack && null != cacheSetting && cacheSetting.EnableCache && null != controlSetting && controlSetting.EnableCache)
                                {
                                    if ((!CacheController.IsCachedUpdating) || (CacheController.IsCachedUpdating &&
                                        IsCachedChanged(QueryStrings.CachedNewsId, QueryStrings.CachedZone, QueryStrings.CachedTagId)))
                                    {
                                        string group = CacheController.GetCacheGroup(controlSetting.GroupKey);
                                        string cacheKey = CacheController.GetCacheKeyName(controlSetting.CacheNameFormat, ClientCacheName);
                                        CacheController.GetMemcachedInstance(ClientCacheName).Add(group, cacheKey, html, controlSetting.CacheExpire);
                                    }
                                }

                                writer.Write(html);
                            }
                            else
                            {
                                if (!string.IsNullOrEmpty(CacheData))
                                {
                                    writer.Write(CacheData + "<!-- (C) -->");
                                }
                                else
                                {
                                    base.Render(writer);
                                }
                            }
                        }
                    }
                }
                else
                {
                    base.Render(writer);
                }
            }
            catch (Exception ex)
            {
                Lib.WriteLogToFile(ex);
                base.Render(writer);
            }
        }
    }
}
